#include "account_service.h"
#include "context.h"
#include "streamdata.h"
#include "log.h"
#include "accountmgr.h"
#include "1700_account.pb.h"

static bool __init__ = AccountService::Instance()->Init();

bool AccountService::Init()
{
    Ctx.msg_router.BindMsg(account_proto::ACCOUNT_CMD_GET_ACCOUNT_BY_UID_RESP, std::bind(&AccountService::OnAccountGet, this, std::placeholders::_1));
    return true;
}

bool AccountService::HandleGetAccount(const std::uint32_t& uid, std::string&& trans, Sence sence)
{
    StreamData stream_data;
    StreamDataWriter write(stream_data);
    write.Write<Sence>(sence);
    write.WriteString(trans);

    account_proto::GetAccountByUidReq account_req;
    account_req.set_uid(uid);
    account_req.set_trans(std::move(stream_data.Data()));
    Ctx.host->MtSendtoSrv(account_proto::ACCOUNT_CMD_GET_ACCOUNT_BY_UID_REQ, SERVER_TYPE_ACCOUNT, &account_req, 0);
    return true;
}

void AccountService::OnAccountGet(MsgData&& data)
{
    do
    {
        account_proto::GetAccountByUidResp Account_get_resp;
        if (!Account_get_resp.ParseFromArray(data.data.c_str(), data.data.size()))
        {
            log_error("parser account_proto::GetResp failed, stype:%d,svid:%d,uuid:%d", data.svtype, data.svid, data.uuid);
            break;
        }

        StreamData stream_data(std::move(*Account_get_resp.mutable_trans()));
        StreamDataReader reader(stream_data);
        Sence sence = reader.Read<Sence>();
        std::string trans = reader.ReadString();

        try
        {
            log_debug("resp:%s", Account_get_resp.ShortDebugString().c_str());
            if (Account_get_resp.err_code() == 0)
            {
                Account account;
                account.uid = Account_get_resp.acc().uid();
                account.agencyid = Account_get_resp.acc().agency_id();
                account.username = Account_get_resp.acc().username();

                AccountMgr::Instance()->SetAccount(account.uid, std::move(account));

                Account* p_Account = AccountMgr::Instance()->GetAccount(account.uid);
                OnSenceAccountGet(sence, std::move(trans), Account_get_resp.err_code(), p_Account);
            }
            else
            {
                OnSenceAccountGet(sence, std::move(trans), Account_get_resp.err_code(), nullptr);
            }
        }
        catch(const std::exception& e)
        {
            log_error("catch exception:%s, sence:%d, stype:%d,svid:%d,uuid:%d,msg:%s", e.what(), sence, data.svtype, data.svid, data.uuid, Account_get_resp.ShortDebugString().c_str());
        }
        catch(...)
        {
            log_error("catch unknown exception, sence:%d, stype:%d,svid:%d,uuid:%d,msg:%s", sence, data.svtype, data.svid, data.uuid, Account_get_resp.ShortDebugString().c_str());
        }
    } while(false);
}

void AccountService::OnSenceAccountGet(Sence sence, std::string&& trans, std::int32_t err_code, Account* pAccount)
{
    auto it = m_account_get_listen.find(sence);
    if (it == m_account_get_listen.end())
    {
        log_warning("sence:%d not listen", sence);
        return;
    }
    it->second(err_code, pAccount, std::move(trans));
}



